package p.sglmsn.top.apale;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class EncryptTabController {
    @FXML
    private TextField sourceFileField;

    @FXML
    private TextField targetFileField;

    @FXML
    private Button encryptBrowseButton;

    @FXML
    private Button encryptButton;

    @FXML
    private VBox encryptBox;

    private List<File> files = new ArrayList<>();

    @FXML
    private void initialize() {
        // 添加拖拽支持
        setupDragAndDrop();
    }

    @FXML
    private void browseSourceFile(ActionEvent event) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择要加密的ZIP文件");
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("ZIP文件", "*.zip"));

        File file = fileChooser.showOpenDialog(encryptBrowseButton.getScene().getWindow());
        if (file != null) {
            sourceFileField.setText(file.getAbsolutePath());
            // 设置默认的目标文件路径
            if (targetFileField.getText().isEmpty()) {
                targetFileField.setText(file.getAbsolutePath() + ".encrypted");
            }
        }
    }

    @FXML
    private void encryptFile(ActionEvent event) {
        String sourcePath = sourceFileField.getText();
        String targetPath = targetFileField.getText();

        if (files == null) {
            if (StrUtil.isNotBlank(sourcePath)) {
                files = List.of(new File(sourcePath));
            }
        }

        if (files != null) {
            for (File sourceFile : files) {
                try {
                    if (sourceFile.isDirectory()) {
                        List<File> files1 = FileUtil.loopFiles(sourcePath, pathname -> pathname
                                .getName().endsWith(".zip"));

                        if (files1.isEmpty()) {
                            System.out.println("没解析到任何内容");
                        }
                        for (File file : files1) {
                            extracted(file, targetPath);
                        }
                    } else {
                        extracted(sourceFile, targetPath);
                    }
                    System.out.println("加密成功完成");
                    files = null;
                } catch (Exception e) {
                    System.out.println("加密失败: " + e.getMessage());
                    e.printStackTrace();
                }
            }
        }

    }

    private void extracted(File sourceFile, String targetPath) throws IOException {
        File targetFile;
        if (StrUtil.isBlank(targetPath)) {
            File Jpgf = new File(sourceFile.getParentFile(), "jpg");
            Jpgf.mkdirs();
            targetFile = new File(Jpgf, sourceFile.getName() + ".jpg");
        } else {
            targetFile = new File(targetPath);
        }
        // 获取图片文件
        HelloApplication application = (HelloApplication) encryptButton.getScene().getWindow().getUserData();
        ImageTabController imageController = application.getImageTabController();

        File imageFile = imageController.getSelectedImageFile();

        // 如果没有选择图片，则使用默认图片
        if (imageFile == null) {
            encryptFileWithDefaultImage(sourceFile, targetFile);
        } else {
            encryptFileWithImage(sourceFile, imageFile, targetFile);
        }
    }

    /**
     * 将图片和ZIP文件合并为一个加密文件
     *
     * @param sourceFile ZIP文件
     * @param imageFile  图片文件
     * @param targetFile 目标文件
     * @throws IOException IO异常
     */
    private void encryptFileWithImage(File sourceFile, File imageFile, File targetFile) throws IOException {
        try (FileInputStream imageInputStream = new FileInputStream(imageFile);
             FileInputStream sourceInputStream = new FileInputStream(sourceFile);
             FileOutputStream targetOutputStream = new FileOutputStream(targetFile)) {

            // 先写入图片数据
            copyStream(imageInputStream, targetOutputStream);

            // 再写入源文件数据
            copyStream(sourceInputStream, targetOutputStream);
        }
    }

    /**
     * 使用默认图片将ZIP文件合并为一个加密文件
     *
     * @param sourceFile ZIP文件
     * @param targetFile 目标文件
     * @throws IOException IO异常
     */
    private void encryptFileWithDefaultImage(File sourceFile, File targetFile) throws IOException {
        InputStream imageInputStream = getClass().getResourceAsStream("/a.jpg");
        if (imageInputStream == null) {
            throw new IOException("默认图片资源 '/a.jpg' 未找到，请确保资源文件存在");
        }

        try (imageInputStream;
             FileInputStream sourceInputStream = new FileInputStream(sourceFile);
             FileOutputStream targetOutputStream = new FileOutputStream(targetFile)) {

            // 先写入默认图片数据
            copyStream(imageInputStream, targetOutputStream);

            // 再写入源文件数据
            copyStream(sourceInputStream, targetOutputStream);
        }
    }

    /**
     * 复制输入流到输出流
     *
     * @param input  输入流
     * @param output 输出流
     * @throws IOException IO异常
     */
    private void copyStream(InputStream input, FileOutputStream output) throws IOException {
        // 根据文件大小选择合适的缓冲区大小
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = input.read(buffer)) != -1) {
            output.write(buffer, 0, bytesRead);
        }
    }

    private void setupDragAndDrop() {
        encryptBox.setOnDragOver(event -> {
            if (event.getGestureSource() != encryptBox && event.getDragboard().hasFiles()) {
                event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
            }
            event.consume();
        });

        encryptBox.setOnDragDropped(event -> {
            Dragboard dragboard = event.getDragboard();
            boolean success = false;
            if (dragboard.hasFiles()) {
                success = true;
                // 支持多文件或目录拖拽，但只使用第一个有效的ZIP文件
                files = dragboard.getFiles();
                for (File file : dragboard.getFiles()) {
                    // 检查文件是否为ZIP文件
                    if (file.getName().toLowerCase().endsWith(".zip")) {
                        sourceFileField.setText(file.getAbsolutePath());
                        // 设置默认的目标文件路径
                        if (targetFileField.getText().isEmpty()) {
                        }
                        break;
                    } else {
                        sourceFileField.setText("只能选择ZIP文件进行加密");
                    }
                }
            }
            event.setDropCompleted(success);
            event.consume();
        });
    }
}